package com.hs.biye.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hs.biye.constant.MessageConstant;
import com.hs.biye.excepction.BaseException;
import com.hs.biye.model.DTO.MedicineRequest;
import com.hs.biye.model.DTO.PutMedicineRequest;
import com.hs.biye.model.VO.MedicineVo;
import com.hs.biye.model.entity.*;
import com.hs.biye.model.reslut.ResultPage;
import com.hs.biye.service.MedicineService;
import com.hs.biye.mapper.MedicineMapper;
import com.hs.biye.service.RegistrationService;
import com.hs.biye.service.SeedoctorService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;


/**
* @author haoshuai
* @description 针对表【medicine】的数据库操作Service实现
* @createDate 2024-02-02 19:16:34
*/
@Service
public class MedicineServiceImpl extends ServiceImpl<MedicineMapper, Medicine>
    implements MedicineService{

    @Resource
    private MedicineMapper medicineMapper;

    @Resource
    private SeedoctorService seedoctorService;
    @Resource
    private RegistrationService registrationService;


    @Override
    public ResultPage<MedicineVo> getPageMedicine(MedicineRequest medicineRequest) {
        if (medicineRequest==null){
            throw new BaseException(MessageConstant.PAR_NOT_RIGHT);
        }
        Integer page = medicineRequest.getPages();
        Integer size = medicineRequest.getSize();
        IPage<Medicine> pages = new Page<>(page,size);
        LambdaQueryWrapper<Medicine> queryWrapper = getQueryWrapper(medicineRequest);
        medicineMapper.selectPage(pages,queryWrapper);

        List<Medicine> records = pages.getRecords();
        long total = pages.getTotal();
        long current = pages.getCurrent();
        long page2 = pages.getPages();

        List<MedicineVo> reslutList = new ArrayList<>();
        records.forEach(item -> {
            MedicineVo medicineVo = new MedicineVo();
            BeanUtils.copyProperties(item,medicineVo);
            reslutList.add(medicineVo);
        });
        return ResultPage.success(reslutList, total,current,page2);
    }

    @Override
    public boolean addMedicine(MedicineRequest medicineRequest) {
        if (medicineRequest==null){
            throw new BaseException(MessageConstant.PAR_NOT_RIGHT);
        }
        String medicineName = medicineRequest.getMedicineName();
        Integer number = medicineRequest.getNumber();
        String medicineType = medicineRequest.getMedicineType();

        if (StringUtils.isEmpty(medicineName)
                || StringUtils.isEmpty(medicineType)
                || number == null){
            throw new BaseException(MessageConstant.PAR_NOT_RIGHT);
        }

        Medicine medicine = new Medicine();
        BeanUtils.copyProperties(medicineRequest,medicine);
        medicine.setPrice(medicine.getPrice() * 100);
        return save(medicine);
    }

    @Override
    public boolean updateMedicine(MedicineRequest medicineRequest) {
        if (medicineRequest==null){
            throw new BaseException(MessageConstant.PAR_NOT_RIGHT);
        }
        Medicine medicine = new Medicine();
        BeanUtils.copyProperties(medicineRequest,medicine);
        medicine.setPrice(medicine.getPrice() * 100);
        return updateById(medicine);
    }

    @Override
    public boolean removeMedicine(Integer id) {
        if (id==null){
            throw new BaseException(MessageConstant.PAR_NOT_RIGHT);
        }
        return removeById(id);
    }

    @Override
    public MedicineVo getMedicineOneById(Integer id) {
        if (id==null){
            throw new BaseException(MessageConstant.PAR_NOT_RIGHT);
        }
        Medicine medicine = getById(id);
        MedicineVo medicineVo = new MedicineVo();
        BeanUtils.copyProperties(medicine,medicineVo);
       return medicineVo;
    }

    @Override
    public  List<HashMap<String, String>> getMedicineType() {
        LambdaQueryWrapper<Medicine> queryWrapper=new LambdaQueryWrapper<>();
        queryWrapper.select(Medicine::getMedicineType).groupBy(Medicine::getMedicineType);
        List<Medicine> medicines = medicineMapper.selectList(queryWrapper);
        List<HashMap<String, String>> res = new ArrayList<>();
        medicines.forEach(item->{
            HashMap<String, String> map = new HashMap<>();
            map.put("medicineType",item.getMedicineType());
            res.add(map);
        });
        return res;
    }

    //配药
    @Override
    @Transactional
    public Boolean putMedicine(PutMedicineRequest putMedicineRequest) {
        if (putMedicineRequest == null){
            throw new BaseException(MessageConstant.PAR_NOT_RIGHT);
        }

        Integer doctorId = putMedicineRequest.getDoctorId();
        Integer patientId = putMedicineRequest.getPatientId();
        String identity = putMedicineRequest.getIdentity();
        Description description = putMedicineRequest.getDescription();

        //更新药品
        AtomicReference<Integer> sum = new AtomicReference<>(0);
        List<Dosage> list = putMedicineRequest.getDescription().getList();
        list.forEach(i->{
            Integer count = i.getCount();
            Integer medicineId = i.getMedicineId();

            //获取药品信息
            Medicine medicine = getById(medicineId);

            //计算药品价格
            Integer number = medicine.getNumber();
            Integer PrePrice = medicine.getPrice();
            i.setPrice(count * PrePrice);
            sum.updateAndGet(v -> v + i.getPrice());

            //更新药品数量
            Medicine newMedicine  = new Medicine();
            newMedicine.setMedicineId(i.getMedicineId());
            newMedicine.setNumber(medicine.getNumber() - count);
            boolean b = updateById(newMedicine);
            if (!b){
                throw new BaseException(MessageConstant.SYSTEM_EOOR);
            }
        });


        Seedoctor seedoctor = new Seedoctor();
        description.setPriceSum(sum.get());
        //添加就诊记录
        seedoctor.setPatientId(patientId);
        seedoctor.setEmployeeId(doctorId);
        seedoctor.setDescription(JSONUtil.toJsonStr(description));
        boolean save = seedoctorService.save(seedoctor);
        if (!save){
            throw new BaseException(MessageConstant.SYSTEM_EOOR);
        }

        Registration registration = new Registration();
        registration.setRegistrationId(putMedicineRequest.getRegistrationId());
        registration.setIsDeal(1);
        return  registrationService.updateById(registration);

    }


    private LambdaQueryWrapper<Medicine> getQueryWrapper(MedicineRequest medicineRequest){

        LambdaQueryWrapper<Medicine> medicineLambdaQueryWrapper = new LambdaQueryWrapper<>();

        Integer medicineId = medicineRequest.getMedicineId();
        String medicineName = medicineRequest.getMedicineName();
        Integer count = medicineRequest.getCount();
        String medicineType = medicineRequest.getMedicineType();
        LocalDateTime createTime = medicineRequest.getCreateTime();
        LocalDateTime updateTime = medicineRequest.getUpdateTime();
        Integer isDelete = medicineRequest.getIsDelete();
        Integer pages = medicineRequest.getPages();
        Integer size = medicineRequest.getSize();


        medicineLambdaQueryWrapper.eq(ObjectUtil.isNotEmpty(medicineId),Medicine::getMedicineId,medicineId);
        medicineLambdaQueryWrapper.eq(ObjectUtil.isNotEmpty(medicineName),Medicine::getMedicineName,medicineName);
        medicineLambdaQueryWrapper.eq(ObjectUtil.isNotEmpty(medicineType),Medicine::getMedicineType,medicineType);
        //排序
        // employeeQueryWrapper.orderBy(true,true,Employee::getCreateTime);

        return medicineLambdaQueryWrapper;
    }
}




